﻿using System;
using System.Collections.Generic;
using System.Text;
using Haozes.FxClient.Sip;
using System.Net.Sockets;
using System.Diagnostics;
using Haozes.FxClient.Core;
using Haozes.FxClient.CommUtil;
using System.IO;
using System.Xml.XPath;
using System.Xml;

namespace Haozes.FxClient
{
    public class ConversationMgr
    {
        private object syncFlag = new object();
        private Dictionary<int, Conversation> convList = new Dictionary<int, Conversation>();
        private SipConnection conncetion = null;
        public event EventHandler<ConversationArgs> MsgReceived;
        /// 他处客户端登录 
        public event EventHandler Deregistered;
        /// 有人添加自己为好友
        public event EventHandler<ConversationArgs> AddBuddyRequest;
        /// 对方同意自己添加其为好友
        public event EventHandler<ConversationArgs> UpdateBuddyRequest;

        public ConversationMgr(SipConnection sipconection)
        {
            this.conncetion = sipconection;
        }

        public Conversation Create(SipMessage packet)
        {
            int callID = int.Parse(packet.CallID.Value);
            Conversation conv = null;
            lock (this.syncFlag)
            {
                if (!this.convList.ContainsKey(callID))
                {
                    conv = new Conversation(this.conncetion, packet);
                    this.convList.Add(callID, conv);
                }
            }
            return conv;
        }

        public Conversation Create(SipMessage packet, bool doSend)
        {
            Conversation conv = this.Create(packet);
            if (doSend)
            {
                this.conncetion.Send(packet);
            }
            return conv;
        }

        public void SendRawPacket(SipMessage packet)
        {
            this.conncetion.Send(packet);
        }

        public Conversation Find(SipMessage packet)
        {
            try
            {
                Conversation c = null;
                int callID = int.Parse(packet.CallID.Value);
                lock (this.convList)
                {
                    if (this.convList.ContainsKey(callID))
                    {
                        c = this.convList[callID];
                        c.CSeq = packet.CSeq.Value;
                    }
                }
                return c;
            }
            catch (Exception ex)
            {
                DebugWriter.WriteLine(packet.ToString());
                throw ex;
            }
        }

        public bool HasConversation(Conversation conv)
        {
            return this.convList.ContainsKey(conv.CallID);
        }

        public void Remove(int callID)
        {
            if (this.convList.ContainsKey(callID))
            {
                lock (this.syncFlag)
                {
                    this.convList.Remove(callID);
                }
            }
        }

        public virtual void RaiseMsgRcv(object sender, ConversationArgs e)
        {
            if (this.MsgReceived != null)
            {
                this.MsgReceived(sender, e);
            }
        }

        public virtual void RaiseDeregistered(object sender, EventArgs e)
        {
            if (this.Deregistered != null)
            {
                this.Deregistered(sender, null);
            }
        }

        public virtual void RaiseAddBuddyApplication(object send, ConversationArgs e)
        {
            if (this.AddBuddyRequest != null)
            {
                string xml = e.Text;
                //TextReader reader = new StringReader(xml);
                //XPathDocument doc = new XPathDocument(reader);
                //XPathNavigator nav = ((IXPathNavigable)doc).CreateNavigator();
                //XPathNodeIterator iter = nav.Select("//application");
                //iter.MoveNext();
                //string uri = iter.Current.GetAttribute("uri", string.Empty);
                //string desc = iter.Current.GetAttribute("desc", string.Empty);
                //e.Text = uri;
                //this.AddBuddyRequest(send, e);

                XmlDocument doc = new XmlDocument();
                doc.LoadXml(xml);
                XmlNode node = doc.SelectSingleNode("//application");
                string uri = node.Attributes["uri"].Value;
                string desc = node.Attributes["desc"].Value;
                e.Text = uri;
                this.AddBuddyRequest(send, e);
            }
        }

        public virtual void RaiseUpdateBuddy(object send, ConversationArgs e)
        {
            if (this.UpdateBuddyRequest != null)
            {
                XmlDocument document = new XmlDocument();
                document.LoadXml(e.Text);
                XmlNode node = document.SelectSingleNode("events/event/contacts/buddies/buddy");
                if (node != null)
                {
                    string uri = XmlHelper.ReadXmlAttributeString(node, "uri");
                    if (!string.IsNullOrEmpty(uri))
                    {
                        //把uri传入text
                        e.Text = uri;
                        this.UpdateBuddyRequest(this, e);
                    }
                }
            }
        }

        public void SendMsg(SipUri uri, string content)
        {
            SipMessage p = PacketFactory.LeaveMsgPacket(uri, content);
            this.conncetion.Send(p);
        }

        public void SendMsg(SipMessage rcvPacket, string msgContent)
        {
            SipMessage p = PacketFactory.ReplyMsgPacket(rcvPacket, msgContent);
            this.conncetion.Send(p);
        }

        public void SendSMS(string mobile, string content)
        {
        }

        public void SendSMS(SipUri uri, string content)
        {
            SipMessage p = PacketFactory.SMSPacket(uri, content);
            this.conncetion.Send(p);
        }
    }
}
